//
// Created by Administrator on 2017/6/1 0001.
//

#ifndef MINISQL_A_API_H
#define MINISQL_A_API_H

#include "Attribute.h"
#include "JudgeCondition.h"
#include "Node.h"
#include "IndexInformation.h"
#include <string>
#include <cstring>
#include <vector>
#include <stdio.h>
#include "table.h"
#include "test_data.h"
#include <fstream>
#define BUCKET_SIZE 20

using namespace std;
class CatalogManager;
class RecordManager;
class IndexManager;
class API {
public:
	RecordManager *Record_Manager_Pointer;
	CatalogManager *Catalog_Manager_Pointer;
	IndexManager *Index_Manager_Pointer;
	API() {}
	~API() {}

	void tableDrop(string tableName);
	void tableCreate(string tableName, vector<Attribute>* attributeVector, string primaryKeyName, int primaryKeyLocation);

	void indexDrop(string indexName);
	void indexCreate(string indexName, string tableName, string attributeName);

	void recordShow(string tableName, vector<string>* attributeNameVector = NULL);
	void recordShow(string tableName, vector<string>* attributeNameVector, vector<Condition>* conditionVector);
    void recordShow(string tableName, vector<string>* attributeNameVector, string key, string attribName);

	void recordInsert(string tableName, vector<string>* recordContent);

	void recordDelete(string tableName);
	void recordDelete(string tableName, vector<Condition>* conditionVector);

	int recordNumGet(string tableName);
	int recordSizeGet(string tableName);

	int typeSizeGet(int type);

	void allIndexAddressInfoGet(vector<IndexInformation> *indexNameVector);

	int attributeNameGet(string tableName, vector<string>* attributeNameVector);
	int attributeTypeGet(string tableName, vector<string>* attributeTypeVector);
	int attributeGet(string tableName, vector<Attribute>* attributeVector);

	void indexValueInsert(string indexName, string value, int blockOffset);

	void indexInsert(string indexName, char* value, int type, int blockOffset);
	void recordIndexDelete(char* recordBegin, int recordSize, vector<Attribute>* attributeVector, int blockOffset);
	void recordIndexInsert(char* recordBegin, int recordSize, vector<Attribute>* attributeVector, int blockOffset);
    int recordCartesianJoinAndShow(string LtableName, string RtableName);
    int recordJoin(string LtableName, string RtableName, vector<Nation> lt, vector<Region> rt);
    int recordJoin(string LtableName, string RtableName, string TtableName, vector<Nation> lt, vector<Region> rt, vector<Customer> tt);
    int recordNotEqualJoin(string LtableName, string RtableName, vector<Nation> lt, vector<Region> rt);
    int recordHashJoin(string LtableName, string RtableName, vector<Nation> lt, vector<Region> rt);
    void MergeSortVector(vector<Nation> ns, vector<Region> rs, vector<Nation> &sortedNs, vector<Region> &sortedRs);
    int recordMergeSortJoin(string LtableName, string RtableName, vector<Nation> lt, vector<Region> rt);
private:
	int tableExist(string tableName);
	int indexNameListGet(string tableName, vector<string>* indexNameVector);
	string primaryIndexNameGet(string tableName);
    void tableAttributePrint(vector<string>* name);
    void writeBucket(int key, string str)
    {
        ofstream buckets("hashMapFile");
        buckets << key << " " << str << endl;
    }
    void readAllBucket()
    {
        int key;
        string str;
        for (int i =0; i < BUCKET_SIZE; i++)
        {
            readBucket(key, str);
        }
    }

    void readBucket(int key, string str)
    {
        ifstream buckets("hashMapFile");
        buckets.read((char*)&key, 4);
    }
    void Merge(int arr[], int start, int mid, int end);
    void MergeSort(int arr[], int start, int end);
};

struct int_t
{
	int value;
};

#endif //MINISQL_A_API_H
